<!--多图片上传组件,直接以base64格式保存在前端-->
<template>
  <div :style="cstyle">
    <div class="upload_container">
      <a-upload
        list-type="picture-card"
        :file-list="fileList"
        :accept="accept"
        :disabled="disabled"
        :before-upload="beforeUpload"
        @preview="handlePreview"
        @change="handleChange"
      >
        <div v-if="fileList.length < max">
          <a-icon type="plus" />
          <div class="ant-upload-text">
            {{ uploadText }}
          </div>
        </div>
      </a-upload>
      <!-- 上传数量 -->
      <div class="upload_count">
        <span class="upload_count_text">{{ `${fileList.length} / ${max} ` }}</span>
      </div>
      <a-modal :visible="previewVisible" :footer="null" @cancel="previewVisible = false">
        <img alt="预览" style="width: 100%" :src="previewImage" />
      </a-modal>
    </div>
  </div>
</template>

<script>
export default {
  name: 'AntPicUpload',
  props: {
    /**
     * 是否禁用
     */
    disabled: {
      type: Boolean,
      default: false
    },
    /**
     * 上传按钮文字
     */
    uploadText: {
      type: String,
      default: '上传图片'
    },
    /**
     * 是否显示上传数量
     */
    showMax: {
      type: Boolean,
      default: true
    },
    /**
     * 最大上传数量，默认1张图片
     */
    max: {
      type: Number,
      default: 1
    },
    /**
     * css样式
     */
    cstyle: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      // 接收图片
      accept: '.jpg,.jpeg,.png',
      // 是否预览
      previewVisible: false,
      // 预览图片
      previewImage: '',
      // 数据源 值类似 [{"uid": "2504210914160000011","name": "2504210914160000011","url": ""}]
      fileList: []
    }
  },
  computed: {

  },
  methods: {
    /**
     * 设置初始化数据
     * @param fileList
     */
    setFileList(fileList) {
      if (Array.isArray(fileList)) {
        this.fileList = fileList
      } else {
        this.$message.warning('数据格式错误！')
      }
    },
    /**
     * 获取数据源
     * @returns {*[]}
     */
    getFileList() {
      return this.fileList
    },
    /**
     * 附件上传前验证是否允许
     * @param file
     * @param fileList
     * @param row
     * @returns {boolean}
     */
    beforeUpload(file, fileList, row) {
      const _this = this
      const accept = this.accept.split(',')
      const fileExtension = file.name.substr(file.name.lastIndexOf('.'))
      if (accept.indexOf(fileExtension) === -1) {
        this.$message.error(`请上传${this.accept}格式的图片！`)
        return false
      }
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = function (e) {
        _this.fileList = [
          ..._this.fileList,
          {
            /**
             * 唯一标识id，不能重复
             */
            uid: file.uid,
            //图片名称，可以重复
            name: file.name,
            //图片 base64 编码
            url: e.target.result
          }
        ]
        _this.$emit('updateFileList', _this.fileList)
      }
      return false
    },
    /**
     * 图片预览
     * @param file
     */
    handlePreview(file) {
      if (file.url) {
        this.previewImage = file.url
      } else if (file.thumbUrl) {
        this.previewImage = file.thumbUrl
      } else if (file.originFileObj) {
        const reader = new FileReader()
        reader.onload = (e) => {
          this.previewImage = e.target.result
        }
        reader.readAsDataURL(file.originFileObj)
      }
      this.previewVisible = true
    },
    /**
     * 文件变化处理
     * @param obj
     */
    handleChange(obj) {
      const { file, fileList } = obj
      if (file.status === 'removed') {
        this.fileList = fileList
        this.$emit('updateFileList', this.fileList)
      }
    }
  }
}
</script>

<style lang="less" scoped>
::v-deep .ant-upload.ant-upload-select-picture-card > .ant-upload {
  height: 100px !important;
}
::v-deep .ant-upload-picture-card-wrapper {
  display: flex;
  width: auto;
}
.ant-upload-text {
  margin-top: 8px;
}

.upload_container {
  position: relative;
  display: inline-block;
  .upload_count {
    position: absolute;
    right: -30px;
    bottom: 5px;
  }
}
</style>
